package vip.aster.monitor.controller;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import vip.aster.common.constant.CacheConstants;
import vip.aster.common.entity.Query;
import vip.aster.common.utils.CacheUtils;
import vip.aster.common.utils.PageInfo;
import vip.aster.common.utils.ResultInfo;
import vip.aster.framework.security.config.TokenStoreCache;
import vip.aster.framework.security.entity.UserDetail;
import vip.aster.monitor.vo.UserOnlineVO;

import java.util.ArrayList;
import java.util.List;

/**
 * 在线用户监控
 *
 * @author Aster
 * @since 2024/2/1 18:05
 */
@RestController
@RequestMapping("/monitor/online")
@AllArgsConstructor
@Tag(name = "在线用户监控")
public class OnlineUserController {
    private final TokenStoreCache tokenStoreCache;

    @GetMapping("/page")
    @Operation(summary = "分页")
    @PreAuthorize("hasAuthority('monitor:online:list')")
    public ResultInfo<PageInfo<UserOnlineVO>> page(@ParameterObject @Valid Query query) {
        // 获取登录用户的全部key
        List<String> keys = tokenStoreCache.getUserKeyList();
        // 逻辑分页
        List<String> keyList = ListUtil.page(query.getPageNum() - 1, query.getPageSize(), keys);

        List<UserOnlineVO> userOnlineList = new ArrayList<>();
        keyList.forEach(key -> {
            UserDetail user = CacheUtils.get(CacheConstants.LOGIN_TOKEN_KEY, key, UserDetail.class);
            if (user != null) {
                UserOnlineVO userOnlineVO = new UserOnlineVO(user);
                userOnlineVO.setTokenId(key);
                userOnlineList.add(userOnlineVO);
            }
        });

        return ResultInfo.success(new PageInfo<>(userOnlineList, keys.size()));
    }

    @GetMapping("/force/{accessToken}")
    @Operation(summary = "强制退出")
    @PreAuthorize("hasAuthority('monitor:online:force')")
    public ResultInfo<String> forceLogout(@PathVariable("accessToken") String accessToken) {
        // token不能为空
        if (StrUtil.isBlank(accessToken)) {
            ResultInfo.failed("token不能为空");
        }

        // 删除用户信息
        tokenStoreCache.deleteUser(accessToken);

        return ResultInfo.success();
    }
}
